#include "Widget.hpp"

#include "Core/Cell.hpp"
#include "Core/RuleData.hpp"
#include "Core/SquareGrid.hpp"

#include "UI/SquareRepresentation.hpp"
#include "UI/Visualisation.hpp"

#include <QtCore/QDebug>
#include <QtCore/QPointF>
#include <QtCore/QTimer>

#include <QtGui/QPushButton>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWheelEvent>

Widget::Widget( QWidget *parent )
    : QWidget( parent )
    , Model( 0 )
    , Scene( 0 )
    , View( 0 )
    , Rules( new RuleData() )
{
    setupGui();
}

Widget::~Widget()
{}

void Widget::setupGui()
{
    QVBoxLayout* mainLayout = new QVBoxLayout( this );
    setLayout( mainLayout );

    Model = new SquareGrid( 100u, 100u, this );

    Rules -> addBirthCondition( 3u );
    Rules -> addSurvivalCondition( 2u );
    Rules -> addSurvivalCondition( 3u );

    Model -> setGameRules( Rules );

    Scene = new SquareRepresentation( Model, this );

    View = new Visualisation( Model, Scene, this );
    mainLayout -> addWidget( View );

    Button = new QPushButton( tr( "initialise" ), this );
    mainLayout -> addWidget( Button );

    connect( Button, SIGNAL( clicked() ), this, SLOT( initMat() ) );
    connect( View, SIGNAL( clickedAt( QPointF ) ), this, SLOT( viewClickedPoint( QPointF ) ) );
    connect( View, SIGNAL( clickedAt( QPointF ) ), Scene, SLOT( retrieveCell( QPointF ) ) );
    connect( Scene, SIGNAL( touchedCell( QPoint ) ), Model, SLOT( flipCell( QPoint ) ) );
}

void Widget::initMat()
{
    QTimer::singleShot( 0 , Model, SLOT( initialise() ) );

    disconnect( Button, SIGNAL( clicked() ), this, SLOT( initMat() ) );

    Button -> setText( tr( "toggle status" ) );

    connect( Button, SIGNAL( clicked() ), this, SLOT( initGrid() ) );
}

void Widget::initGrid()
{
    // still life - Block
    /*
    QTimer::singleShot( 0 , Model -> operator()( 1u, 1u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 2u, 1u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 1u, 2u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 2u, 2u ), SLOT( toggleCurrentStatus() ) );
    */
    // still life - beehive
    /*
    QTimer::singleShot( 0 , Model -> operator()( 1u, 2u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 1u, 3u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 2u, 1u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 2u, 4u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 3u, 2u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 3u, 3u ), SLOT( toggleCurrentStatus() ) );
    */
    // oscillator - Blinker
    /*
    QTimer::singleShot( 0 , Model -> operator()( 0u, 1u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 1u, 1u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 2u, 1u ), SLOT( toggleCurrentStatus() ) );
    */
    // oscillator - Beacon
    QTimer::singleShot( 0 , Model -> operator()( 0u, 0u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 0u, 1u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 1u, 0u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 1u, 1u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 2u, 2u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 2u, 3u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 3u, 2u ), SLOT( toggleCurrentStatus() ) );
    QTimer::singleShot( 0 , Model -> operator()( 3u, 3u ), SLOT( toggleCurrentStatus() ) );


    disconnect( Button, SIGNAL( clicked() ), this, SLOT( initGrid() ) );

    Button -> setText( tr( "step" ) );

    connect( Button, SIGNAL( clicked() ), this, SLOT( callStep() ) );
}

void Widget::callStep()
{
    qDebug() << "------- step -------";
    QTimer::singleShot( 0, Model, SLOT( step() ) );
    update();
}

void Widget::viewClickedPoint( const QPointF& pt )
{
    qDebug() << "Clicked at" << pt;
}
